package com.chuangke.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chuangke.admin.dao.SysDictTypeDaoService;
import com.chuangke.admin.data.builder.UserDataBuilder;
import com.chuangke.admin.entity.SysDictType;
import com.chuangke.admin.service.SysDictTypeService;
import com.chuangke.common.constant.CacheKeyConstants;
import com.chuangke.common.data.builder.DataBuildConfig;
import com.chuangke.common.data.builder.DataBuilder;
import com.chuangke.common.db.page.CkPageQuery;
import com.chuangke.common.db.page.PageUtil;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 字典类型Service业务层处理
 *
 * @author chuangke
 * @date "2020-07-21"
 */
@Service
public class SysDictTypeServiceImpl implements SysDictTypeService {

    @Autowired
    private SysDictTypeDaoService sysDictTypeDaoService;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    @CacheEvict(cacheNames = CacheKeyConstants.SYS_DICT_TYPE, key = "'" + CacheKeyConstants.SYS_DICT_TYPE + "'")
    public void save(SysDictType record) {
        sysDictTypeDaoService.saveOrUpdate(record);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    @CacheEvict(cacheNames = CacheKeyConstants.SYS_DICT_TYPE, key = "'" + CacheKeyConstants.SYS_DICT_TYPE + "'")
    public void save(List<SysDictType> records) {
        sysDictTypeDaoService.saveOrUpdateBatch(records);
    }

    @Transactional(rollbackFor = Throwable.class)
    @CacheEvict(cacheNames = CacheKeyConstants.SYS_DICT_TYPE, key = "'" + CacheKeyConstants.SYS_DICT_TYPE + "'")
    public void doUpdateBatch(List<SysDictType> list) {
        sysDictTypeDaoService.updateBatchById(list);
    }

    @Transactional(rollbackFor = Throwable.class)
    @CacheEvict(cacheNames = CacheKeyConstants.SYS_DICT_TYPE, key = "'" + CacheKeyConstants.SYS_DICT_TYPE + "'")
    @Override
    public void delete(SysDictType record) {
        sysDictTypeDaoService.removeById(record);
    }

    @Transactional(rollbackFor = Throwable.class)
    @CacheEvict(cacheNames = CacheKeyConstants.SYS_DICT_TYPE, key = "'" + CacheKeyConstants.SYS_DICT_TYPE + "'")
    @Override
    public void delete(List<SysDictType> records) {
        sysDictTypeDaoService.removeBatchByIds(records);
    }

    @Transactional(rollbackFor = Throwable.class)
    @CacheEvict(cacheNames = CacheKeyConstants.SYS_DICT_TYPE, key = "'" + CacheKeyConstants.SYS_DICT_TYPE + "'")
    @Override
    public void deleteByIds(List<String> ids) {
        sysDictTypeDaoService.removeByIds(ids);
    }

    @Transactional(rollbackFor = Throwable.class)
    @CacheEvict(cacheNames = CacheKeyConstants.SYS_DICT_TYPE, key = "'" + CacheKeyConstants.SYS_DICT_TYPE + "'")
    @Override
    public void deleteByType(List<String> types) {
        sysDictTypeDaoService.remove(new QueryWrapper<SysDictType>().lambda().in(SysDictType::getCode, types));
    }

    @Cacheable(cacheNames = CacheKeyConstants.SYS_DICT_TYPE, key = "'" + CacheKeyConstants.SYS_DICT_TYPE + "'")
    @Override
    public Map<String, SysDictType> findMap() {
        List<SysDictType> list = sysDictTypeDaoService.list();
        DataBuilder.of(list)
        .appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName"),
                new DataBuildConfig("updatedBy", "updatedByName")).build();
        return list.stream().collect(Collectors.toMap(SysDictType::getId, a -> a));
    }

    @Override
    public List<SysDictType> findList() {
        Map<String, SysDictType> map = ((SysDictTypeService) AopContext.currentProxy()).findMap();
        return new ArrayList<>(map.values());
    }

    @Override
    public SysDictType findById(String id) {
        if (id == null) {
            return null;
        }

        Map<String, SysDictType> map = ((SysDictTypeService) AopContext.currentProxy()).findMap();
        return map.get(id);
    }

    @Override
    public SysDictType findByType(String type) {
        Map<String, SysDictType> map = ((SysDictTypeService) AopContext.currentProxy()).findMap();
        Map<String, SysDictType> typeMap = map.values().stream().collect(Collectors.toMap(SysDictType::getCode, a -> a));
        return typeMap.get(type);
    }


    @Override
    public IPage<SysDictType> page(CkPageQuery page) {
        List<SysDictType> list = ((SysDictTypeService) AopContext.currentProxy()).findList();

        String name = (String) page.get("name");

        list = list.stream().filter(dictType -> ((StrUtil.isBlank(name) || (StrUtil.isNotBlank(name)
                && (dictType.getCode().contains(name) || dictType.getName().contains(name)))
        ))).collect(Collectors.toList());

        DataBuilder.of(list)
                .appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName"),
                        new DataBuildConfig("updatedBy", "updatedByName")).build();
        return PageUtil.findPage(page, list);
    }

}
